ServiceBag
Installation
npm install @quenty/servicebag --save
Goals
- Remove requirement for many services to be loaded
- Make installing new modules really easy
- Make testing easier
- Reduce maintaince costs
- Explicitly declare service pattern
- Force declaration of service usage
- Make it easy to trace service dependencies
Requirements
- Initialize dependent services using
:Init()
- Start dependent services using
:Start()
- Retrieve services is easy
- Don't have to list off every service in the game
- Services don't load until we ask them to
- Circular dependencies allowed
Like-to-have
- Dependency injection for tests
- Works with type system
GetService<IService>()
- Async initialization (return promises instead of blocking)
- Dependency graph safe (i.e. recursive service requirement )
- Services are protected from another service erroring
Stretch goals
- Handles services for actors (remove global code)
Ideas
Rules
- Each service will be identified by its module
- Each service will be initialized once
- If we require a service, we will not have to declare subservices
local serviceBag = require("ServiceBag").new()
serviceBag:AddService(require("TransparencyService"))
serviceBag:Init()
serviceBag:Start()
local TransparencyService = require("TransparencyService")
local TestClass = {}
TestClass.ClassName = "TestClass"
TestClass.__index = TestClass
function TestClass.new(serviceBag)
local self = setmetatable({}, TestClass)
self._serviceProvider = assert(serviceBag, "No serviceBag")
self._transparencyService = self._serviceProvider:GetRequiredService(TransparencyService)
return self
end
return TestClass
local DialogPane = setmetatable({}, BasicPane)
DialogPane.ClassName = "DialogPane"
DialogPane.__index = DialogPane
function DialogPane.new(serviceBag)
local self = setmetatable(BasicPane.new(serviceBag:GetService(DialogTemplatesClient):Clone("DialogPaneTemplate")), DialogPane)
self._theme = Instance.new("StringValue")
self._theme.Value = "Light"
self._maid:GiveTask(self._theme)
self._dialogInput = DialogInput.new()
self._maid:GiveTask(self._dialogInput)